#include "LineList.h"

#define DEFAULT_COLOR (DirectX::XMFLOAT3(1.0f, 1.0f, 1.0f))

LineList::LineList()
	: m_numVertices(0),
	m_vertices(nullptr)
{
}

LineList::LineList(const LineList& other)
	: m_numVertices(other.m_numVertices),
	m_vertices(new LineVertex[m_numVertices])
{
	LineVertex* otherVertex = other.m_vertices;
	for(LineVertex* memberVertex = m_vertices; memberVertex < m_vertices + m_numVertices; ++memberVertex)
	{

		*memberVertex = *otherVertex;
		++otherVertex;
	}
}

LineList& LineList::operator=( const LineList& other )
{
	LineList::~LineList();
	m_numVertices = other.m_numVertices;
	m_vertices = new LineVertex[m_numVertices];
	LineVertex* otherVertex = other.m_vertices;
	for(LineVertex* memberVertex = m_vertices; memberVertex < m_vertices + m_numVertices; ++memberVertex)
	{

		*memberVertex = *otherVertex;
		++otherVertex;
	}
	return *this;
}

LineList::LineList( const LineVertex* vertices, int numVertices )
	: m_vertices(new LineVertex[numVertices]),
	m_numVertices(numVertices)
{
	for(LineVertex* memberVertex = m_vertices; memberVertex < m_vertices + m_numVertices; ++memberVertex)
	{
		*memberVertex = *vertices;
		++vertices;
	}
}

LineList::LineList( const DirectX::XMFLOAT3* positions, DirectX::XMFLOAT3 color, int numVertices )
	: m_vertices(new LineVertex[numVertices]),
	m_numVertices(numVertices)
{
	for(LineVertex* memberVertex = m_vertices; memberVertex < m_vertices + m_numVertices; ++memberVertex)
	{
		memberVertex->Pos = *positions;
		memberVertex->Color = color;
		++positions;
	}
}

LineList::LineList( const DirectX::XMFLOAT3* positions, int numVertices )
{
	for(LineVertex* memberVertex = m_vertices; memberVertex < m_vertices + numVertices; ++memberVertex)
	{
		memberVertex->Pos = *positions;
		memberVertex->Color = DEFAULT_COLOR;
		++positions;
	}
}


LineList::~LineList(void)
{
	delete m_vertices;
	if(m_renderData.VertexBuffer)
	{
		m_renderData.VertexBuffer->Release();
		m_renderData.VertexBuffer = nullptr;
	}
}

HRESULT LineList::InitializeD3D( ID3D11Device* d3dDevice )
{
	using namespace DirectX;
	HRESULT result;
	m_renderData.VertexStride = sizeof(LineVertex);
	m_renderData.VertexOffset = 0;

	//Create vertex buffer
	D3D11_BUFFER_DESC bufferDesc;
	ZeroMemory( &bufferDesc, sizeof(bufferDesc) );
	bufferDesc.Usage = D3D11_USAGE_DEFAULT;
	bufferDesc.ByteWidth = sizeof( LineVertex ) * m_numVertices;
	bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
	bufferDesc.CPUAccessFlags = 0;
	D3D11_SUBRESOURCE_DATA bufferInitializationData;
	ZeroMemory( &bufferInitializationData, sizeof(bufferInitializationData) );
	bufferInitializationData.pSysMem = m_vertices;
	result = d3dDevice->CreateBuffer( &bufferDesc, &bufferInitializationData, &m_renderData.VertexBuffer );
	if( FAILED( result ) )
	{
		return result;
	}
	return S_OK;
}

HRESULT LineList::UpdateD3d( ID3D11DeviceContext* d3dContext )
{
	if(m_renderData.VertexBuffer)
	{
		d3dContext->UpdateSubresource(m_renderData.VertexBuffer,
			0,
			nullptr,
			m_vertices,
			0,
			0);
		return S_OK;
	}
	return E_FAIL;
}

void LineList::ClearD3d( void )
{
	if(m_renderData.VertexBuffer)
	{
		m_renderData.VertexBuffer->Release();
	}
	m_renderData.VertexBuffer = nullptr;
}
